package tools

import (
	"errors"
	"fmt"
	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/disk"
	"github.com/shirou/gopsutil/host"
	"github.com/shirou/gopsutil/mem"
	"golang.org/x/text/encoding/simplifiedchinese"
	"net"
	"os"
	"os/exec"
	"os/user"
	"strings"
	"time"
)

// GetIpaddress 获取本地ip地址
// 参考链接 https://www.jianshu.com/p/301aabc06972
func GetIpaddress() []string {
	var ips []string = nil
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		fmt.Println(err)
		return ips
	}

	for _, address := range addrs {
		// 检查ip地址判断是否回环地址
		if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				ips = append(ips, ipnet.IP.String())
			}
		}
	}
	return ips
}

func ShowNetInfo(args []string) (err error) {
	interfaces, err := net.Interfaces()
	if err != nil {
		return errors.New("获取接口地址失败:" + err.Error())
	}

	for _, i := range interfaces {
		// 不显示本地回环地址
		if i.HardwareAddr == nil {
			continue
		}
		// 显示接口信息
		Out(Prefix, "网卡名称:", i.Name)
		// 显示ip地址
		addrs, _ := i.Addrs()
		for _, addr := range addrs {
			// 只显示ipv4地址
			if len(addr.String()) > 18 {
				continue
			}
			Out(ItemPrefix, "ip信息:", addr.String())
		}
		// 显示MAC地址
		Out(ItemPrefix, "MAC地址:", i.HardwareAddr)
	}
	return nil
}

func Hostname() string {
	hostname, _ := os.Hostname()
	return hostname
}

func CurrentUsername() string {
	current, _ := user.Current()
	if IsWindows() {
		return strings.Split(current.Username, `\`)[1]
	} else {
		return current.Username
	}
}

func WindowsSystemInfo() {
	output, err := exec.Command("systeminfo").CombinedOutput()
	if err != nil {
		Out(err.Error())
		return
	}
	bytes, err := simplifiedchinese.GBK.NewDecoder().Bytes(output)
	if err != nil {
		Out(err.Error())
		return
	}
	outInfo := string(bytes)
	items := strings.Split(outInfo, "\r\n")
	for _, v := range items {
		if strings.Contains(v, "物理内存总量") {
			Out(v)
			continue
		}
		if strings.Contains(v, "OS 名称") {
			Out(v)
			continue
		}
		if strings.Contains(v, "OS 版本") {
			Out(v)
			continue
		}
		if strings.Contains(v, "系统制造商") {
			Out(v)
			continue
		}
		if strings.Contains(v, "BIOS 版本") {
			Out(v)
			continue
		}
		if strings.Contains(v, "初始安装日期") {
			Out(v)
			continue
		}
		if strings.Contains(v, "系统启动时间") {
			Out(v)
			continue
		}
	}
}

// 获取系统启动时间
func GetBootTime() string {
	timestamp, _ := host.BootTime()
	t := time.Unix(int64(timestamp), 0)
	return t.Local().Format(TimeFmt)
}

// CPU内存使用率
func CpuMemRate() {
	// CPU使用率
	fmt.Print("CPU使用率:")
	percents, _ := cpu.Percent(time.Second, false)
	for _, v := range percents {
		FmtOut("%d%%\n", int(v))
	}

	// 内存使用情况
	memoryStat, _ := mem.VirtualMemory()
	FmtOut("Total:%dM Available:%dM Used:%d%%\n", memoryStat.Total/1024/1024, memoryStat.Available/1024/1024, int(memoryStat.UsedPercent))
}

// 内存大小
func GetMemSize() int {
	memoryStat, _ := mem.VirtualMemory()
	return int(memoryStat.Total / 1024 / 1024)
}

func GetOSVersion() string {
	// 操作系统信息
	platform, _, version, _ := host.PlatformInformation()
	return fmt.Sprintf("%s(%s)", platform, version)
}

func GetCPUInfo() string {
	// 显示CPU信息
	info, _ := cpu.Info()
	ret := ""
	for _, v := range info {
		ret += v.ModelName
	}
	return ret
}

func GetDiskPartitionInfo() string {
	// 磁盘容量使用情况
	partitions, _ := disk.Partitions(true)
	ret := ""
	for _, partition := range partitions {
		stat, _ := disk.Usage(partition.Device)
		ret += fmt.Sprintf("%s Total %dG,Used %d%% ", partition.Device, stat.Total/1024/1024/1024, int(stat.UsedPercent))
	}
	return ret
}

func PCInfo(args []string) (err error) {
	ItemStdout("OS version:", GetOSVersion())
	ItemStdout("CPU:", GetCPUInfo())
	ItemStdout("Memory Size:", fmt.Sprintf("%dM", GetMemSize()))
	ItemStdout("Disk Size:", GetDiskPartitionInfo())
	ItemStdout("OS Boot Time:", GetBootTime())

	return nil
	//CpuMemRate()
}

func SystemTool() *Option {
	return &Option{"ifconfig", ShowNetInfo, "查看网络信息."}
}
